﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using RotovapPlatform.Domain.Business.Recipes.Entities;
using static RotovapPlatform.Domain.Business.Machine.Enums.ExperimentConfigEnums;

namespace RotovapPlatform.UI.ViewModels.ExperimentManagement
{
	/// <summary>
	/// 实验组视图模型，包装ExperimentGroup实体并实现属性变更通知
	/// </summary>
	public class ExperimentGroupViewModel : INotifyPropertyChanged
	{
		private readonly ExperimentGroup _experimentGroup;
		private ObservableCollection<ExperimentViewModel> _experiments;
		private ExperimentViewModel _selectedExperiment;

		/// <summary>
		/// 属性变更事件
		/// </summary>
		public event PropertyChangedEventHandler PropertyChanged;

		/// <summary>
		/// 构造函数
		/// </summary>
		/// <param name="experimentGroup">要包装的实验组实体</param>
		public ExperimentGroupViewModel(ExperimentGroup experimentGroup)
		{
			_experimentGroup = experimentGroup ?? throw new ArgumentNullException(nameof(experimentGroup));

			// 初始化实验视图模型集合
			InitializeExperiments();
		}

		/// <summary>
		/// 初始化实验视图模型集合
		/// </summary>
		private void InitializeExperiments()
		{
			_experiments = new ObservableCollection<ExperimentViewModel>();

			if (_experimentGroup.Experiments != null)
			{
				foreach (var experiment in _experimentGroup.Experiments)
				{
					_experiments.Add(new ExperimentViewModel(experiment));
				}
			}
		}

		/// <summary>
		/// 获取被包装的实验组实体
		/// </summary>
		public ExperimentGroup ExperimentGroup => _experimentGroup;

		/// <summary>
		/// 实验组ID
		/// </summary>
		public Guid GroupId => _experimentGroup.GroupId;

		/// <summary>
		/// 实验组名称
		/// </summary>
		public string GroupName => _experimentGroup.GroupName;

		/// <summary>
		/// 实验组描述
		/// </summary>
		public string Description => _experimentGroup.Description;

		/// <summary>
		/// 实验组创建时间
		/// </summary>
		public DateTime CreatedTime => _experimentGroup.CreatedTime;

		/// <summary>
		/// 实验组创建人
		/// </summary>
		public string Creator => _experimentGroup.Creator;

		/// <summary>
		/// 实验组状态
		/// </summary>
		public ExperimentGroupStatus Status
		{
			get => _experimentGroup.Status;
			set
			{
				if (_experimentGroup.Status != value)
				{
					_experimentGroup.Status = value;
					OnPropertyChanged();
				}
			}
		}

		/// <summary>
		/// 实验组执行进度
		/// </summary>
		public double ExecutionProgress
		{
			get => _experimentGroup.ExecutionProgress;
			set
			{
				if (Math.Abs(_experimentGroup.ExecutionProgress - value) > 0.01)
				{
					_experimentGroup.ExecutionProgress = value;
					OnPropertyChanged();
				}
			}
		}

		/// <summary>
		/// 实验组执行开始时间
		/// </summary>
		public DateTime? ExecutionStartTime
		{
			get => _experimentGroup.ExecutionStartTime;
			set
			{
				if (_experimentGroup.ExecutionStartTime != value)
				{
					_experimentGroup.ExecutionStartTime = value;
					OnPropertyChanged();
				}
			}
		}

		/// <summary>
		/// 实验组执行结束时间
		/// </summary>
		public DateTime? ExecutionEndTime
		{
			get => _experimentGroup.ExecutionEndTime;
			set
			{
				if (_experimentGroup.ExecutionEndTime != value)
				{
					_experimentGroup.ExecutionEndTime = value;
					OnPropertyChanged();
				}
			}
		}

		/// <summary>
		/// 实验组中的实验视图模型集合
		/// </summary>
		public ObservableCollection<ExperimentViewModel> Experiments
		{
			get => _experiments;
			private set
			{
				if (_experiments != value)
				{
					_experiments = value;
					OnPropertyChanged();
				}
			}
		}

		/// <summary>
		/// 选中的实验
		/// </summary>
		public ExperimentViewModel SelectedExperiment
		{
			get => _selectedExperiment;
			set
			{
				if (_selectedExperiment != value)
				{
					_selectedExperiment = value;
					OnPropertyChanged();
				}
			}
		}

		/// <summary>
		/// 更新实验组状态
		/// </summary>
		public void UpdateStatus()
		{
			_experimentGroup.UpdateStatus();
			OnPropertyChanged(nameof(Status));
		}

		/// <summary>
		/// 计算实验组进度
		/// </summary>
		public void CalculateProgress()
		{
			_experimentGroup.CalculateProgress();
			OnPropertyChanged(nameof(ExecutionProgress));
		}

		/// <summary>
		/// 添加或更新实验
		/// </summary>
		/// <param name="experiment">要添加或更新的实验</param>
		public void AddOrUpdateExperiment(Experiment experiment)
		{
			if (experiment == null)
				return;

			var existingViewModel = Experiments.FirstOrDefault(vm => vm.ExperimentId == experiment.ExperimentId);

			if (existingViewModel != null)
			{
				// 更新现有实验
				existingViewModel.UpdateFrom(experiment);
			}
			else
			{
				// 添加新实验到原始集合
				if (_experimentGroup.Experiments == null)
				{
					_experimentGroup.Experiments = new ObservableCollection<Experiment>();
				}
				_experimentGroup.Experiments.Add(experiment);

				// 添加新的视图模型
				Experiments.Add(new ExperimentViewModel(experiment));
			}

			// 更新实验组状态和进度
			UpdateStatus();
			CalculateProgress();
		}

		/// <summary>
		/// 更新指定实验ID的实验信息
		/// </summary>
		/// <param name="experimentId">实验ID</param>
		/// <param name="updatedExperiment">更新后的实验实体</param>
		/// <returns>是否找到并更新了实验</returns>
		public bool UpdateExperiment(Guid experimentId, Experiment updatedExperiment)
		{
			if (updatedExperiment == null)
				return false;

			var existingViewModel = Experiments.FirstOrDefault(vm => vm.ExperimentId == experimentId);
			if (existingViewModel != null)
			{
				existingViewModel.UpdateFrom(updatedExperiment);

				// 更新实验组状态和进度
				UpdateStatus();
				CalculateProgress();
				return true;
			}

			return false;
		}

		/// <summary>
		/// 更新指定实验的信息
		/// </summary>
		/// <param name="updatedExperiment">更新后的实验实体</param>
		/// <returns>是否找到并更新了实验</returns>
		public bool UpdateExperiment(Experiment updatedExperiment)
		{
			if (updatedExperiment == null)
				return false;

			return UpdateExperiment(updatedExperiment.ExperimentId, updatedExperiment);
		}

		/// <summary>
		/// 从实体对象更新属性
		/// </summary>
		/// <param name="entity">实验组实体</param>
		public void UpdateFromEntity(ExperimentGroup entity)
		{
			if (entity == null || entity.GroupId != GroupId)
				return;

			// 更新所有相关属性
			Status = entity.Status;
			ExecutionProgress = entity.ExecutionProgress;
			ExecutionStartTime = entity.ExecutionStartTime;
			ExecutionEndTime = entity.ExecutionEndTime;

			// 如果有更多需要更新的属性，可以在这里添加

			// 通知所有属性已更改
			OnPropertyChanged(string.Empty);
		}

		/// <summary>
		/// 通知属性变更
		/// </summary>
		/// <param name="propertyName">变更的属性名称</param>
		protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
		{
			PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
		}
	}
}